# -*- coding: utf-8 -*-
"""
根据【年份】参数，
利用【多值提取至点】工具，将各个因子提取至栅格单元矢量点

"""
import sys
import os
import arcpy
import pandas as pd
from util_batch_del_fields import batch_del_fields

def ZonalSt_forSlopeUnits(slopUnit_fc, slope_zonal_ID, factor_raster, statistic_type="MEAN"):
    """
        利用斜坡单元统计个栅格因子图层的分区统计信息

    :param slopUnit_fc: str
        斜坡单元的路径名称

    :param slope_zonal_ID: str
        斜坡单元ID列名称

    :param factor_raster: str
        因子图层的名称，必须符合：factor_因子名称的形式
    :param statistic_type:str
        统计类型，可以为MEAN，MAJORITY，MAXIMUM，MINIMUM，MEDIAN，MINORITY

    :return:
        执行不成功返回None；成功返回输出的表格字符串

    """
    if slopUnit_fc is None or slope_zonal_ID is None or factor_raster is None:
        return None
    if slopUnit_fc == "" or slope_zonal_ID == "" or factor_raster == "":
        return None

    factor_name = factor_raster.split("_")[1]
    # arcpy.sa.ZonalStatisticsAsTable("SlopeUnits_V3", "OBJECTID", "Factor_DEM",
    #                                 r"G:\DataForDoctorPaper\博士论文数据.gdb\Zon_DEM", "DATA", "MEAN")
    # step 1: execute Zonal Statistics
    tmp_zonalst_output = "Zon_{0}".format(factor_name)
    if arcpy.Exists(tmp_zonalst_output):
        arcpy.Delete_management(tmp_zonalst_output)
    zonal_re = arcpy.sa.ZonalStatisticsAsTable(slopUnit_fc, slope_zonal_ID, factor_raster,
                                               tmp_zonalst_output,
                                               "DATA", statistic_type)

    if zonal_re.status == 4:
        return tmp_zonalst_output
    else:
        return None

def alter_zonalstTable_field(zonal_table, factor_name, sta_type):

    # alter statistic field name
    old_field = sta_type
    new_field = "{0}_{1}".format(factor_name, sta_type)
    alter_field_re = arcpy.management.AlterField(zonal_table, old_field, new_field, new_field)

    # alter ID field name
    old_ID_field = "OBJECTID_1"
    new_ID_field = "ID_{0}".format(factor_name)
    id_re = arcpy.management.AlterField(zonal_table, old_ID_field, new_ID_field, new_ID_field)

    # delete field that not needed
    drop_fields = ["COUNT", "AREA"]
    arcpy.management.DeleteField(zonal_table, drop_fields)

    if (alter_field_re.status == 4) and (id_re.status == 4):
        return zonal_table, new_ID_field
    else:
        return None, None

def join_slopeUnits_zonalTable(slopeUnits_fc, zonal_table, zonal_ID, slopUnits_id="OBJECTID", year = 2010 ):

    # AddJoin_management第一个参数必须是layer图层；由于input_fc是要素类，需要转化为layer图层
    desc = arcpy.Describe(slopeUnits_fc)
    if hasattr(desc, "dataType") and desc.dataType == "FeatureClass":
        fc_layer_name = slopeUnits_fc
        arcpy.MakeFeatureLayer_management(slopeUnits_fc,  fc_layer_name)
    elif hasattr(desc, "dataType") and desc.dataType == "FeatureLayer":
        fc_layer_name = slopeUnits_fc

    re_join = arcpy.JoinField_management(fc_layer_name, slopUnits_id, zonal_table, zonal_ID)
    return fc_layer_name
    # rename_tmp_output = "tmp"
    # arcpy.Rename_management(fc_layer_name, rename_tmp_output, data_type="FeatureClass")
    # if re_join.status == 4:
    #     export_tmp_fc = "tmp_slopeUnits_{0}".format(year)
    #     # print(export_tmp_fc)
    #     re_copy = arcpy.CopyFeatures_management(rename_tmp_output, export_tmp_fc)
    #     if re_copy.status == 4:
    #         return export_tmp_fc
    # else:
    #     return None


def exact_factors_forSlopeUnits(input_fc='SlopeUnits_V5',slope_zonal_ID = "OBJECTID",
                                year=2003, del_exist_fields=True,
                                statics_settings = None, data_version= "V5"):

    export_tmp_fc = "slopeUnits_{0}_{1}".format(data_version, year)

    # 首先读取设置文件，包含因子列表和各自的统计类型
    if not os.path.exists(statics_settings):
        arcpy.AddError("Please produce setting file: '{0}' first!".format(statics_settings))
        sys.exit(1)

    df_settings = pd.read_csv(statics_settings, encoding="gb2312")

    # 删除已经存在的字段
    if del_exist_fields:
        field_obj_list = arcpy.ListFields(input_fc)
        f_list = [f.name for f in field_obj_list]
        # ObjectID, shape_area等字段不能被删除，所以要排除掉
        f_list.remove("OBJECTID")
        f_list.remove("Shape")
        if "Shape_Length" in f_list:
            f_list.remove("Shape_Length")
        if "Shape_Area" in f_list:
            f_list.remove("Shape_Area")

        del_field_str = ";".join(f_list)
        # print(del_field_str)
        if del_field_str is not None and len(del_field_str) != 0:
            arcpy.management.DeleteField(input_fc, del_field_str)

    # step 1 & 2 % 3: 分区统计；删除分区统计表中的不必要字段；将分区表与斜坡单元连接起来
    for d in df_settings.values:
        factor_raster = d[0]
        sta_type = d[1]
        # 如果因子图层factor_raster不存在，则跳过当前循环
        if not arcpy.Exists(factor_raster):
            arcpy.AddMessage("file '{0}' does not exist".format(factor_raster))
            continue
        # （1）分区统计
        zonal_re = ZonalSt_forSlopeUnits(input_fc, slope_zonal_ID, factor_raster, statistic_type=sta_type)
        if zonal_re is None:
            arcpy.AddMessage("Exact {0} faieled!".format(factor_raster))
            continue

        # （2）删除分区统计表中的不必要字段；
        if factor_raster.startswith("Factor_"):
            factor_name = factor_raster.split("_")[1]
        else:
            factor_name = factor_raster

        zonal_table, zonal_id = alter_zonalstTable_field(zonal_table=zonal_re, factor_name=factor_name,
                                                         sta_type=sta_type)
        if zonal_table is None or zonal_id is None:
            arcpy.AddMessage("alter zonalTable field {0} faieled!".format(zonal_re))
            continue

        # （3）将分区表与斜坡单元连接起来
        current_tmp_fc = join_slopeUnits_zonalTable(slopeUnits_fc=input_fc,
                                                    zonal_table=zonal_table,
                                                    zonal_ID=zonal_id,
                                                    slopUnits_id=slope_zonal_ID,
                                                    year=year)
        arcpy.AddMessage("Exact {0} successful!".format(factor_raster))

        #     # 如果都成功执行，则删除中间文件
        #     arcpy.Delete_management(input_fc)
        #     arcpy.Delete_management(zonal_table)

    # Step 3：将连接起来的斜坡单元要素重新复制一份
    if arcpy.Exists(export_tmp_fc):
        arcpy.Delete_management(export_tmp_fc)
    re_copy = arcpy.CopyFeatures_management(input_fc, export_tmp_fc)

    # Step 4: 删除不必要的字段
    del_wildcard = "ID_"
    batch_del_fields(export_tmp_fc, del_wildcard)

    if re_copy.status == 4:
        arcpy.AddMessage("the exaction for slope units successful:")
        arcpy.AddMessage("result file: '{0}'".format(export_tmp_fc))
        return export_tmp_fc
    else:
        return None


if __name__=="__main__":
    # 工具箱模式
    input_fc = arcpy.GetParameterAsText(0)
    slope_zonal_ID = arcpy.GetParameterAsText(1)
    year = int(arcpy.GetParameterAsText(2))
    del_exist_fields = arcpy.GetParameter(3)
    data_version = arcpy.GetParameterAsText(4)

    current_file_dir = os.path.split(os.path.realpath(__file__))[0]
    results_dir = current_file_dir + "/settings"
    if not os.path.exists(results_dir):
        os.makedirs(results_dir)

    # # Set the current workspace
    # arcpy.env.workspace = "G:/DataForDoctorPaper/博士论文数据.gdb"
    # input_fc = 'SlopeUnits_V5'
    # slope_zonal_ID = 'OBJECTID'
    # year = 2003
    # del_exist_fields = True
    # data_version = "V5"
    # results_dir = "./settings"

    statics_settings = "{0}/slopeSettings_{1}.csv".format(results_dir, year)
    exact_factors_forSlopeUnits(input_fc=input_fc,
                                slope_zonal_ID=slope_zonal_ID,
                                year=year,
                                del_exist_fields=del_exist_fields,
                                statics_settings=statics_settings,
                                data_version=data_version)






    # try:
    #     arcpy.sa.ExtractMultiValuesToPoints(input_fc, rain_field_str, "NONE")
    # except arcpy.ExecuteError:
    #     arcpy.AddError(arcpy.GetMessages(2))
